package com.filter;

import com.bean.Remark;
import com.service.RemarkService;
import com.service.SensitiveService;
import com.service.WordsService;
import com.tools.SensitiveWordInit;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.sql.SQLException;
import java.util.*;

public class SensitiveFilter implements Filter {
    public static Map sensitiveWordMap = null;
    /**
     * 只过滤最小敏感词
     */
    public static int minMatchType = 1;
    /**
     * 过滤所有敏感词
     */
    public static int maxMatchType = 2;
    SensitiveService service=new SensitiveService();
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        try {
            Set<String> set=service.getAllSensitive();
        } catch (Exception throwables) {
            throwables.printStackTrace();
            System.out.println("获取敏感词库失败！！！");
        }

    }

    /**
     * 把敏感词加入到HashMap
     *单个字单个字加进Map，过滤掉，
     * @param keyWordSet
     * @return
     */
    public Map addSensitiveWordToHashMap(Set<String> keyWordSet){
        sensitiveWordMap  = new HashMap(keyWordSet.size());
        Map nowMap = null;
        Iterator iterator = keyWordSet.iterator();
        while(iterator.hasNext()){
            String str = (String) iterator.next();
            nowMap = sensitiveWordMap;
            Object wordMap =null;
            for(int i = 0;i<str.length();i++){
                char word = str.charAt(i);
                if(word!='，'||word!=','||word!='.'||word!='。'||word!='！'||word!='!'||word!='?'||word!='？'||word!='-'||word!='_'||word!='—'){
                    wordMap = word;
                }
                if(wordMap!=null ){
                    nowMap.put(wordMap,i);
                }else{
                    Map<String,String> newMap = new HashMap<String,String>();
                    newMap.put("isEnd","0");
                    nowMap.put(word,newMap);
                    nowMap = newMap;
                }
                if(i==str.length()-1){
                    nowMap.put("isEnd","1");
                }
            }
        }
        return sensitiveWordMap;
    }



    public Map strSensitiveWordToHashMap(Set<String> keyWordSet) {
        sensitiveWordMap = new HashMap(keyWordSet.size());
        Map nowMap = null;
        Iterator iterator = keyWordSet.iterator();
        while (iterator.hasNext()) {
            String str = (String) iterator.next();
            nowMap = sensitiveWordMap;
            if (str.length() == 0) {
                Map<String, String> newMap = new HashMap<String, String>();
                newMap.put("isEnd", "0");
                nowMap.put(null, newMap);
                nowMap = newMap;
            }
            int start = 0;
            int count = 0;
            for (int i = 0; i < str.length(); i++) {
                Object strMap = null;
                if (str.charAt(i) == '，' || i == str.length() - 1) {
                    if (i == str.length() - 1) {
                        strMap = str.substring(start);
                        nowMap.put(strMap, count);
                        nowMap.put("isEnd", "1");
                    } else {
                        strMap = str.substring(start, i);
                        nowMap.put(strMap, count);
                    }
                    start = i + 1;
                    count++;

                } else {
                    continue;
                }
            }
        }
        return sensitiveWordMap;
    }

    /**
     * 返回从beginIndex开始的敏感词长度
     *
     * @param txt
     * @param beginIndex
     * @param matchType
     * @return
     */
    public static int checkSensitiveWordSum(String txt, int beginIndex, int matchType) throws Exception {
        SensitiveWordInit init=new SensitiveWordInit();
        Set<String> set=init.LoadSetitiveWord();
        Map sensitiveWordMap=init.addSensitiveWordToHashMap(set);


        boolean flag = false;
        int sensitiveSum = 0;   //返回敏感词长度

        for (int i = beginIndex; i < txt.length(); i++) {
            char key = txt.charAt(i);
            //sensitiveWordMap = (Map) map.get(key);
            if (  sensitiveWordMap.get(key) != null) {
                sensitiveSum++;
                if (sensitiveWordMap.get("isEnd").equals("1")) {
                    flag = true;
                    if (matchType == minMatchType) {
                        break;
                    }
                }
            } else {
                break;
            }
        }
        if (!flag || sensitiveSum < 2) {
            sensitiveSum = 0;
        }
        return sensitiveSum;
    }

    /**
     * 获取txt文本中的敏感词并保存
     * 为后续的replaceAll方法做准备工作
     *
     * @param txt
     * @param matchType
     * @return
     */
    public static Set<String> getSensitiveWord(String txt, int matchType) throws Exception {
        SensitiveWordInit init=new SensitiveWordInit();
        Set<String> set=init.LoadSetitiveWord();
        Map map=init.strSensitiveWordToHashMap(set);
        Set<String> sensitiveWord = new HashSet<String>();

        for (int i = 0; i < txt.length(); i++) {
            int sum = checkSensitiveWordSum(txt, i, matchType);
            if (sum > 0) {
                // 将检测出的敏感词保存到集合中
                String tempword=txt.substring(i, i + sum);
                if(map.get(tempword)!=null){
                    sensitiveWord.add(tempword);
                }

                //sensitiveWord.add(txt.substring(i, i + sum));
                i = i + sum - 1;   //减一的目的是i下一次循环递增了
            }
        }

        return sensitiveWord;
    }

    /**
     * 替换敏感词
     * 无论敏感词长度多大，默认替代字符“***”
     *
     * @param txt
     * @param matchType
     * @return
     */
    public static String replaceSensitiveWord(String txt, int matchType) throws Exception {
        String resultTxt = txt;
        Set<String> set = getSensitiveWord(txt, matchType);
        Iterator<String> iterator = set.iterator();
        String word = null;   //敏感词
        String replaceTxt = "***";   // 替换字符，这里默认“***”
        while (iterator.hasNext()) {
            word = iterator.next();
            resultTxt = resultTxt.replaceAll(word, replaceTxt);
        }
        return resultTxt;
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {


        HttpServletRequest request=(HttpServletRequest) servletRequest;
        HttpServletResponse response=(HttpServletResponse) servletResponse;

        HttpSession session=request.getSession();
        String reContent= (String) request.getSession().getAttribute("orRemark");
        String woContent= (String) request.getSession().getAttribute("word");
        RemarkService remarkService=new RemarkService();
        WordsService wordsService=new WordsService();
        Remark remark=new Remark();

        if(reContent!=null){
            try {
                String recontent=replaceSensitiveWord(reContent,2);
                remark.setRecontent(recontent);
                session.setAttribute("remark",remark);


            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        if(woContent!=null){
            try {
                replaceSensitiveWord(woContent,2);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    @Override
    public void destroy() {
        Filter.super.destroy();
    }
}
